package com.campus.common.service.impl;

import com.campus.common.domain.LoginUser;
import com.campus.common.domain.User;
import com.campus.common.dto.UserDto;
import com.campus.common.exception.SystemException;
import com.campus.common.exception.SystemExceptionCode;
import com.campus.common.mapper.AuthorityMapper;
import com.campus.common.mapper.UserMapper;
import com.campus.common.service.LoginUserService;
import com.campus.common.utils.RedisCache;
import jakarta.annotation.Resource;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class LoginUserServiceImpl implements LoginUserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private AuthorityMapper authorityMapper;
    @Resource
    private RedisCache redisCache;
    @Override
    public LoginUser loginByUsername(UserDto userDto) {

        User user = userMapper.selectByUsername(userDto.getUsername());
        return setLoginUser(userDto, user);
    }

    @Override
    public LoginUser loginByPhoneNumber(UserDto userDto) throws UsernameNotFoundException {
        User user = userMapper.selectByPhoneNumber(userDto.getPhoneNumber());
        return setLoginUser(userDto, user);
    }

    @Override
    public LoginUser loginByEmail(UserDto userDto) throws UsernameNotFoundException {
        User user = userMapper.selectByEmail(userDto.getEmail());
        return setLoginUser(userDto, user);
    }
    // 如果用户密码校验成功， 查询权限并进行封装
    private LoginUser setLoginUser(UserDto userDto, User user) {
        if (user != null) {
            if(this.authenticate(userDto.getPassword(), user.getPassword())) {
                List<String> authorityList = authorityMapper.getAuthorityByUserId(user.getUserId());
                // TODO 将用户信息装入dto中
                userDto.setUserId(user.getUserId());
                LoginUser loginUser = new LoginUser(userDto, authorityList);
                redisCache.setCacheObject("loginUser:id: " + userDto.getUserId().toString(), loginUser);
                return loginUser;
            }
        }
        throw new SystemException(SystemExceptionCode.USER_LOGIN_ERROR);
    }

    @Override
    public Boolean authenticate(String loginPassword, String password) {
        return passwordEncoder.matches(loginPassword, password);
    }

}
